/* file: zm_exec.c */

#include "zm.h"
#include "zm_exec.h"

int exec_code()
{
	int pc = 0;
	code_seg curr_code = code_mem[pc];
	OP_CODE op;
	int data1, data2;
	int temp1, temp2, flag1, flag2, temp;

	op = curr_code.op_code;

	top = 0;
	while(op != -1)
	{
		data1 = curr_code.data1.data;
		data2 = curr_code.data2.data;
		flag1 = curr_code.data1.flag;
		flag2 = curr_code.data2.flag;
		switch(op)
		{
			case MOV:
				if((flag1 == REG_FLAG) && (flag2 == DATA_FLAG))
					reg[data1] = data2;
				else if((flag1 == REG_FLAG) && (flag2 == MEM_FLAG))
					reg[data1] = data_mem[data2];
				else if((flag1 == MEM_FLAG) && (flag2 == REG_FLAG))
					data_mem[data1] = reg[data2];
				else 
					printf("error\n");
				pc++;
				break; 
			case PUSH:
				if(flag1 == REG_FLAG)
					stack_mem[top++] = reg[data1];
				pc++;
				break;
			case POP:
				if(flag1 == REG_FLAG)
					reg[data1] = stack_mem[--top] ;
				pc++;
				break;
			case XCHG:
				if((flag1 == REG_FLAG) && (flag2 == REG_FLAG))
					temp = reg[data1], reg[data1] = reg[data2], reg[data2] = temp;
				pc++;
				break;
			case ADD:
				if((flag1 == REG_FLAG) && (flag2 == REG_FLAG))
					reg[data1] = reg[data1] + reg[data2];
				pc++;
				break;
			case SUB:
				if((flag1 == REG_FLAG) && (flag2 == REG_FLAG))
					reg[data1] = reg[data1] - reg[data2];
				pc++;
				break;
			case MUL:
				if((flag1 == REG_FLAG) && (flag2 == REG_FLAG))
					reg[data1] = reg[data1] * reg[data2];
				pc++;
				break;
			case DIV:
				if((flag1 == REG_FLAG) && (flag2 == REG_FLAG))
					reg[data1] = reg[data1] / reg[data2];
				pc++;
				break;
			case JNE:
				if(flag1 == MEM_FLAG)
					if(reg[0] != 0)
						pc = data1;
					else
						pc++;
				break;
			case JLS:
				if(flag1 == MEM_FLAG)
					if(reg[0] < 0)
						pc = data1;
					else
						pc++;
				break;
			case JLE:
				if(flag1 == MEM_FLAG)
					if(reg[0] <= 0)
						pc = data1;
					else
						pc++;
				break;
			case  JGT:
				if(flag1 == MEM_FLAG)
					if(reg[0] > 0)
						pc = data1;
					else
						pc++;
				break;
			case JGE:
				if(flag1 == MEM_FLAG)
					if(reg[0] >= 0)
						pc = data1;
					else
						pc++;
				break;
			case JEQ:
				if(flag1 == MEM_FLAG)
					if(reg[0] == 0)
						pc = data1;
					else
						pc++;
				break;
			case  JMP:
				if(flag1 == MEM_FLAG)
					pc = data1;
				break;
			case OUT:
				printf("The result is %d\n", reg[0]);
				pc++;
				break;
			case IN:
				printf("Please input a integer number:");
				scanf("%d",&reg[0]);
				printf("\n");
				pc++;
				break;
		}
		curr_code = code_mem[pc];
		op = curr_code.op_code;
	}
	return 1;

}
